package com.company.cloud.goodsrestservice.core;


import org.apache.ibatis.exceptions.TooManyResultsException;
import org.springframework.beans.factory.annotation.Autowired;
import tk.mybatis.mapper.entity.Condition;

import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.util.List;

/**
 * 基于通用MyBatis Mapper插件的Service接口的实现
 */
public abstract class AbstractService<T> implements Service<T> {

    @Autowired
    protected Mapper<T> mapper;

    private Class<T> modelClass;    // 当前泛型真实类型的Class

    public AbstractService() {
        ParameterizedType pt = (ParameterizedType) this.getClass().getGenericSuperclass();
        modelClass = (Class<T>) pt.getActualTypeArguments()[0];
    }

    public void save(T model) {
        mapper.insertSelective(model);
    }

    public void save(List<T> models) {
        mapper.insertList(models);
    }

    public void deleteById(Integer id) {
        mapper.deleteByPrimaryKey(id);
    }

    public void deleteByIds(String ids) {
        mapper.deleteByIds(ids);
    }

    public void update(T model) {
            mapper.updateByPrimaryKeySelective(model);
    }

    public T findById(Integer id) {
        return mapper.selectByPrimaryKey(id);
    }

    @Override
    public T findBy(String fieldName, Object value) throws TooManyResultsException {
        try {
            T model = modelClass.newInstance();
            Field field = modelClass.getDeclaredField(fieldName);
            field.setAccessible(true);
            field.set(model, value);
            return mapper.selectOne(model);
        } catch (ReflectiveOperationException e) {
            throw new ServiceException(e.getMessage(), e);
        }
    }

    public List<T> findByIds(String ids) {
        return mapper.selectByIds(ids);
    }

    public List<T> findByCondition(Condition condition) {
        return mapper.selectByCondition(condition);
    }

    public List<T> findAll() {
        return mapper.selectAll();
    }

    @Override
    public List<T> findBySearch(String key, Object value) {
        try {
            T m = modelClass.newInstance();
            Field f = modelClass.getDeclaredField(key);
            f.setAccessible(true);
            f.set(m, value);
            return mapper.select(m);
        } catch (Exception e) {
            throw new ServiceException(e.getMessage(), e);
        }
    }

    /*    public Map checkInsert(T model) {
        Map ret = new HashMap();
        Boolean _new = false;
        T m = mapper.selectOne(model);
        if (m == null) {
            try {
                Field createTime = modelClass.getDeclaredField("createTime");
                createTime.setAccessible(true);
                createTime.set(model, (int)System.currentTimeMillis());
                mapper.insert(model);
                _new = true;
                m = mapper.selectOne(model);
            } catch (Exception e) {
                m = null;
                _new = false;
            }
        }

        ret.put("obj", m);
        ret.put("is_new", _new);
        return ret;
//        return m;
    }*/
}
